package com.zbkj.front.service.impl;


import com.zbkj.dal.base.enums.*;
import com.zbkj.dal.base.enums.merchant.MerOrderApptType;
import com.zbkj.dal.common.enums.ExpressType;
import com.zbkj.dal.common.utils.DateConverter;
import com.zbkj.dal.entity.ba.Share;
import com.zbkj.dal.entity.merchant.Merchant;
import com.zbkj.dal.entity.order.OrderAddress;
import com.zbkj.dal.entity.order.OrderInvoice;
import com.zbkj.dal.entity.product.ProductBrand;
import com.zbkj.dal.entity.user.UserAddress;
import com.zbkj.dal.pojo.response.OrderInvoiceResponse;
import com.zbkj.dal.pojo.response.ba.ShareDetailResponse;
import com.zbkj.front.model.req.ArriveStoreAfterInitialEvaluationReq;
import com.zbkj.front.model.req.PickupAfterInitialEvaluationReq;
import com.zbkj.front.model.req.PickupModifyAfterInitialEvaluationReq;
import com.zbkj.service.model.vo.ArriveStoreAddressVO;
import com.zbkj.front.model.vo.SharePickupInfoVO;
import com.zbkj.front.model.vo.SupplyEstimateConfirmVO;
import com.zbkj.front.service.ApiSheShareService;
import com.zbkj.service.manager.ExpressManager;
import com.zbkj.service.model.dto.address.OrderAddressCreateDTO;
import com.zbkj.service.model.dto.express.CreateExpressDTO;
import com.zbkj.service.model.dto.order.OrderMerAppointmentDTO;
import com.zbkj.service.service.*;
import com.zbkj.service.service.merchant.MerchantOrderAppointmentService;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.util.Assert;

import java.math.BigDecimal;
import java.math.RoundingMode;
import java.time.LocalDateTime;

@Service
public class ApiSheShareServiceImpl implements ApiSheShareService {

    @Autowired
    private OrderAddressService orderAddressService;
    @Autowired
    private OrderInvoiceService orderInvoiceService;
    @Autowired
    private ShareService shareService;
    @Autowired
    private MerchantService merchantService;
    @Autowired
    private MerchantOrderAppointmentService merchantOrderAppointmentService;
    @Autowired
    private UserAddressService userAddressService;
    @Autowired
    private ExpressManager expressManager;
    @Autowired
    private ProductBrandService productBrandService;

    @Override
    public ArriveStoreAddressVO evaluationStroeAddress() {
        Merchant merchant = merchantService.getShareServiceMerchant();
        Assert.notNull(merchant, "总店地址不存在");
        return new ArriveStoreAddressVO(merchant);
    }

    @Override
    public ShareDetailResponse.PickUpAppt pickupAfterInitialEvaluation(PickupAfterInitialEvaluationReq req, Integer userId) {
        Share share = shareService.getByOrderNo(req.getOrderNo());
        // 只有给了初评结果，才能操作预约上门
        Assert.isTrue(StringUtils.equals(BizSharedOrderStatus.PENDING_SHIPMENT.name(), share.getStatus()), "只有初评阶段才能操作物流寄送");
        // 获取预约时间编码对应的时间
        PickupAppointmentAvailableTime availableTime = PickupAppointmentAvailableTime.getByCode(req.getPickupCode());
        final LocalDateTime pickupTime = req.getPickupDate().atTime(availableTime.getStart());
        // 供享信息
        ProductBrand brand = productBrandService.getById(share.getBrandFinal());
        String productName = brand.getName() + ProductTypeEnums.valueOf(share.getProductType()).getDesc();
        // 收方地址
        Merchant merchant = merchantService.getShareServiceMerchant();
        Assert.notNull(merchant, "总店地址不存在");
        orderAddressService.insertAddress(req.getOrderNo(), OrderAddressType.RECEIVER, ExpressOrderType.SHARED_INITIAL_EVALUATION_RCV, OrderAddressCreateDTO.buildByMerchantAddress(merchant));
        // 寄方地址
        UserAddress userAddress = userAddressService.getById(req.getAddressId());
        Assert.notNull(userAddress, "收货地址不存在");
        orderAddressService.insertAddress(req.getOrderNo(), OrderAddressType.SHIPPER, ExpressOrderType.SHARED_INITIAL_EVALUATION_RCV, OrderAddressCreateDTO.buildByUserAddress(userAddress));
        // 创建一个物流订单， 收方付款， 物流订单类型为 【供享订单 初评收货】
        CreateExpressDTO expressOrder = expressManager.createExpressOrderWithPickupCode(req.getOrderNo(), productName ,pickupTime, ExpressOrderPayMethodType.RECEIVER_PAY, ExpressOrderType.SHARED_INITIAL_EVALUATION_RCV);
        // 创建一个订单信息
        OrderInvoice orderInvoice = new OrderInvoice();
        orderInvoice.setOrderNo(req.getOrderNo());
        orderInvoice.setExpressOrderNo(expressOrder.getExpressOrder());
        orderInvoice.setExpressOrderType(ExpressOrderType.SHARED_INITIAL_EVALUATION_RCV.name());
        orderInvoice.setMerId(1);
        orderInvoice.setUid(userId);
        orderInvoice.setTrackingNumber(expressOrder.getExpressNumber());
        orderInvoice.setExpressName(ExpressType.SF.getName());
        orderInvoice.setExpressCode(ExpressType.SF.getCode());
        orderInvoice.setTotalNum(1);
        // 上门时间 & 取件码
        orderInvoice.setPickupTime(pickupTime);
        orderInvoice.setPickupCode(expressOrder.getPickupCode());
        //
        orderInvoice.setStatus(OrderInvoceStatus.WAITING.getCode());
        orderInvoice.setCreateTime(LocalDateTime.now());
        orderInvoice.setUpdateTime(LocalDateTime.now());
        orderInvoiceService.save(orderInvoice);
        // 更新供享订单信息
        shareService.updateShareExpressDelivery(req.getOrderNo(), userId);

        // 接口返回预约结果信息
        ShareDetailResponse.PickUpAppt pickUpAppt = new ShareDetailResponse.PickUpAppt();
        pickUpAppt.setDeliveryName(ExpressType.SF.getName());
        pickUpAppt.setPickupCode(expressOrder.getPickupCode());
        pickUpAppt.setSenderName(userAddress.getRealName());
        pickUpAppt.setSenderPhone(userAddress.getPhone());
        pickUpAppt.setSenderAddress(userAddress.getProvince() + userAddress.getCity() + userAddress.getDistrict() + userAddress.getDetail());
        pickUpAppt.setDateDesc(DateConverter.convertDate(req.getPickupDate()));
        pickUpAppt.setStartTime(availableTime.getStart());
        pickUpAppt.setEndTime(availableTime.getEnd());
        return pickUpAppt;
    }

    @Override
    public SharePickupInfoVO pickupInfo(String orderNo) {
        OrderInvoiceResponse orderInvoice = orderInvoiceService.findOneByOrderNoAndOrderType(orderNo, ExpressOrderType.SHARED_INITIAL_EVALUATION_RCV);
        OrderAddress orderAddress = orderAddressService.getOneOrderAddressList(orderNo, OrderAddressType.SHIPPER, ExpressOrderType.SHARED_INITIAL_EVALUATION_RCV);
        return SharePickupInfoVO.build(orderInvoice, orderAddress);
    }

    @Override
    public void pickupCancel(String orderNo) {
        orderInvoiceService.cnacelExpressOrder(orderNo, ExpressOrderType.SHARED_INITIAL_EVALUATION_RCV);
        Share share = shareService.getByOrderNo(orderNo);
        // 状态设置为待寄送
        share.setStatus(BizSharedOrderStatus.PENDING_SHIPMENT.name());
        share.setSubStatus(StringUtils.EMPTY);
        shareService.updateByEntity(share);
    }

    @Override
    public void pickupUpdate(PickupModifyAfterInitialEvaluationReq req) {
        // 获取预约时间编码对应的时间
        PickupAppointmentAvailableTime availableTime = PickupAppointmentAvailableTime.getByCode(req.getPickupCode());
        // 获取到OrderInvoice更新上门时间
        orderInvoiceService.updateExpressOrderPickupTime(req.getOrderNo(), ExpressOrderType.SHARED_INITIAL_EVALUATION_RCV, req.getPickupDate().atTime(availableTime.getStart()));
    }

    @Override
    public ShareDetailResponse.InStoreAppt arriveStoreAfterInitialEvaluationReq(ArriveStoreAfterInitialEvaluationReq req, Integer userId) {
        Share share = shareService.getByOrderNo(req.getOrderNo());
        // 只有给了初评结果，才能操作预约上门
        Assert.isTrue(StringUtils.equals(BizSharedOrderStatus.PENDING_SHIPMENT.name(), share.getStatus()), "只有初评阶段才能操作到店估价");
        // 获取预约时间编码对应的时间
        PickupAppointmentAvailableTime availableTime = PickupAppointmentAvailableTime.getByCode(req.getEvaluationTimeCode());
        // 预约记录
        OrderMerAppointmentDTO merchantOrderAppointment = merchantOrderAppointmentService.createMerchantOrderAppointment(req.getOrderNo(), 1, userId, req.getEvaluationTimeDate(), availableTime.getStart(), availableTime.getEnd(), MerOrderApptType.SHARED_CREATE);
        shareService.updateShareEvaluationTime(req.getOrderNo(), req.getEvaluationTimeDate().atTime(availableTime.getStart()), req.getEvaluationTimeDate().atTime(availableTime.getEnd()), userId);
        ArriveStoreAddressVO arriveStoreAddressVO = evaluationStroeAddress();
        ShareDetailResponse.InStoreAppt inStoreAppt = new ShareDetailResponse.InStoreAppt();
        inStoreAppt.setReservationNo(merchantOrderAppointment.getApptCode());
        inStoreAppt.setName(arriveStoreAddressVO.getStoreName());
        inStoreAppt.setPhone(arriveStoreAddressVO.getStorePhone());
        inStoreAppt.setAddress(arriveStoreAddressVO.getProvince() + arriveStoreAddressVO.getCity() + arriveStoreAddressVO.getDistrict() + arriveStoreAddressVO.getStoreAddress());
        inStoreAppt.setLatitude(arriveStoreAddressVO.getLatitude());
        inStoreAppt.setLongitude(arriveStoreAddressVO.getLongitude());
        inStoreAppt.setDateDesc(DateConverter.convertDate(req.getEvaluationTimeDate()));
        inStoreAppt.setStartTime(availableTime.getStart());
        inStoreAppt.setEndTime(availableTime.getEnd());
        return inStoreAppt;
    }

    @Override
    public void arriveStoreCancel(String orderNo) {
        merchantOrderAppointmentService.cancelMerchantOrderAppointment(orderNo, MerOrderApptType.SHARED_CREATE);
        Share share = shareService.getByOrderNo(orderNo);
        // 状态设置为待寄送
        share.setStatus(BizSharedOrderStatus.PENDING_SHIPMENT.name());
        share.setSubStatus(StringUtils.EMPTY);
        shareService.updateByEntity(share);
    }

    @Override
    public void arriveStoreUpdate(ArriveStoreAfterInitialEvaluationReq req, Integer userId) {
        PickupAppointmentAvailableTime availableTime = PickupAppointmentAvailableTime.getByCode(req.getEvaluationTimeCode());
        merchantOrderAppointmentService.modifyMerchantOrderAppointmentTime(req.getOrderNo(), MerOrderApptType.SHARED_CREATE, req.getEvaluationTimeDate(), availableTime.getStart(), availableTime.getEnd());
        shareService.updateShareEvaluationTime(req.getOrderNo(), req.getEvaluationTimeDate().atTime(availableTime.getStart()), req.getEvaluationTimeDate().atTime(availableTime.getEnd()), userId);
    }

    @Override
    public SupplyEstimateConfirmVO estimateConfirm(String orderNo, Integer userId) {
        // 确认估价，预计会生成 quota 额度， 和  balance 的雅识
        shareService.estimateConfirm(orderNo, userId);
        Share share = shareService.getByOrderNo(orderNo);
        SupplyEstimateConfirmVO supplyEstimateConfirmVO = new SupplyEstimateConfirmVO();
        supplyEstimateConfirmVO.setQuota(share.getEstimatePriceFinal().toPlainString());
        supplyEstimateConfirmVO.setBalance(share.getEstimatePriceFinal().multiply(BigDecimal.valueOf(0.05)).setScale(2, RoundingMode.DOWN).toPlainString());
        return supplyEstimateConfirmVO;
    }
}
